package cn.buk.tms.eotms.dao;

import cn.buk.common.util.DateUtil;
import cn.buk.tms.eotms.dao.factory.OperationLogFactory;
import cn.buk.tms.eotms.entity.FlightRefundOrder;
import cn.buk.tms.eotms.entity.FlightRefundOrder_;
import cn.buk.tms.eotms.entity.OperationLog;
import cn.buk.tms.eotms.sc.SearchFlightOrderCriteria;
import org.springframework.stereotype.Component;

import jakarta.persistence.criteria.*;
import jakarta.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;

@Component
@Transactional
public class RefundOrderDaoImpl extends AbstractDao implements RefundOrderDao {

  @Override
  public List<FlightRefundOrder> searchFlightRefundOrder(final int ownerId, final int customerId,
      SearchFlightOrderCriteria sc) {
    List<FlightRefundOrder> results = null;

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<FlightRefundOrder> cq = cb.createQuery(FlightRefundOrder.class);
    Root<FlightRefundOrder> root = cq.from(FlightRefundOrder.class);
    root.alias("o");

    var predicates0 = getPredicates_searchFlightRefundOrder(ownerId, customerId, sc, cb, root);

    //计算根据条件查询得出的数据总数
    CriteriaQuery<Long> countQuery = cb.createQuery(Long.class);
    Root<FlightRefundOrder> countRoot = countQuery.from(FlightRefundOrder.class);
    countRoot.alias("o");

    var predicates1 = getPredicates_searchFlightRefundOrder(ownerId, customerId, sc, cb, countRoot);

    countQuery.select(cb.count(countRoot)).where(predicates1.toArray(new Predicate[predicates1.size()]));
    Long count = em.createQuery(countQuery).getSingleResult();

    int maxResults = count.intValue();
    if (maxResults > 0) {
      cq.where(predicates0.toArray(new Predicate[predicates0.size()]));
      List<jakarta.persistence.criteria.Order> orderByes = new ArrayList<>();
      orderByes.add(cb.desc(root.get("id")));

      cq.orderBy(orderByes);

      sc.getPage().setRowCount(maxResults);
      results = em.createQuery(cq)
          .setFirstResult(sc.getPage().getFirstPosition())
          .setMaxResults(sc.getPage().getPageSize()).getResultList();
    }


    if (results == null) {
      results = new ArrayList<>();
    }

    return results;
  }

  private List<Predicate> getPredicates_searchFlightRefundOrder(int ownerId, int customerId, SearchFlightOrderCriteria sc, CriteriaBuilder cb, Root<FlightRefundOrder> root) {
    List<Predicate> predicates = new ArrayList<>();

    Predicate predicate = cb.conjunction();
    predicates.add(predicate);

    predicate = cb.equal(root.get(FlightRefundOrder_.enterpriseId), ownerId);
    predicates.add(predicate);


    predicate = cb.equal(root.get(FlightRefundOrder_.customerId), customerId);
    predicates.add(predicate);

    if (sc.getBalCode() != null && sc.getTicketNo() != null) {
      if (sc.getBalCode().length() == 3 && sc.getTicketNo().length() == 10) {
        predicate = cb.equal(root.get(FlightRefundOrder_.balanceCode), sc.getBalCode());
        predicates.add(predicate);

        predicate = cb.equal(root.get(FlightRefundOrder_.ticketNo), sc.getTicketNo());
        predicates.add(predicate);
      }
    }

    if (sc.getIntlTicket() > -1) {
      predicate = cb.equal(root.get(FlightRefundOrder_.intlTicket), sc.getIntlTicket());
      predicates.add(predicate);
    }

    if (sc.getName() != null && sc.getName().trim().length() > 0) {
      predicate = cb.like(root.get(FlightRefundOrder_.psgName), "%" + sc.getName().trim() + "%");
      predicates.add(predicate);
    }

    if (sc.getStatus() > -1) {
      predicate = cb.equal(root.get(FlightRefundOrder_.status), sc.getStatus());
      predicates.add(predicate);
    }

    if (sc.getTicketNo().length() > 0) {
      String temp = sc.getTicketNo().trim();
      if (temp.length() > 10) {
        temp = temp.substring(temp.length() - 10);
      }
      if (temp.length() < 10) {
        predicate = cb.like(root.get(FlightRefundOrder_.ticketNo), "%" + temp + "%");
      } else {
        // length = 10
        predicate = cb.equal(root.get(FlightRefundOrder_.ticketNo), temp);
      }
      predicates.add(predicate);
    }

    if (sc.getBeginDate() != null) {
      predicate = cb.greaterThanOrEqualTo(root.get(FlightRefundOrder_.createTime), sc.getBeginDate());
      predicates.add(predicate);
    }

    if (sc.getEndDate() != null) {
      predicate = cb.lessThanOrEqualTo(root.get(FlightRefundOrder_.createTime), DateUtil
          .addDays(sc.getEndDate(), 1));
      predicates.add(predicate);
    }

    if (sc.getIdno() != null && sc.getIdno().trim().length() > 0) {
      predicate = cb.like(root.get(FlightRefundOrder_.idNo), "%" + sc.getIdno().trim() + "%");
      predicates.add(predicate);
    }

    if (sc.getName() != null && sc.getName().trim().length() > 0) {
      predicate = cb.like(root.get(FlightRefundOrder_.psgName), "%" + sc.getName().trim() + "%");
      predicates.add(predicate);
    }

    if (sc.getOrderNo().length() > 0) {
      predicate = cb.equal(root.get(FlightRefundOrder_.orderNo), sc.getOrderNo());
      predicates.add(predicate);
    }

    if (sc.getRefundOrderNo().length() > 0) {
      predicate = cb.equal(root.get(FlightRefundOrder_.refundOrderNo), sc.getRefundOrderNo());
      predicates.add(predicate);
    }

    if (sc.getAirRefundStatus() == 0) {
      predicate = cb.isNull(root.get(FlightRefundOrder_.airRefundStatus));
      predicate = cb.or(predicate, cb.equal(root.get(FlightRefundOrder_.airRefundStatus), 0));
      predicates.add(predicate);
    } else if (sc.getAirRefundStatus() == 1) {
      predicate = cb.equal(root.get(FlightRefundOrder_.airRefundStatus), 1);
      predicates.add(predicate);
    }

    if (sc.getOp1().length() > 0) {
      //查找指定用户名的订单
      predicate = cb.equal(root.get(FlightRefundOrder_.operator), sc.getOp1());
      predicates.add(predicate);
    }
    if (sc.getDepartmentId() != null) {
      //只查找本部门的
      List<String> usernames = doGetCustomerDepartmentOperator(ownerId, customerId, sc.getDepartmentId());

      Path<String> path = root.get(FlightRefundOrder_.operator);
      CriteriaBuilder.In<String> in = cb.in(path);
      for(String username: usernames) {
        in.value(username);
      }

      predicates.add(in);
    }
    return predicates;
  }

  @Override
  public List<FlightRefundOrder> searchByFlightOrderNo(int ownerId, String orderNo) {
    return em.createQuery("select o from FlightRefundOrder o where o.enterpriseId = :enterpriseId and o.orderNo = :orderNo", FlightRefundOrder.class)
        .setParameter("enterpriseId", ownerId)
        .setParameter("orderNo", orderNo)
        .getResultList();
  }

  @Override
  public FlightRefundOrder getFlightRefundOrderDetail(int id) {
    return em.find(FlightRefundOrder.class, id);
  }

  @Override
  public int createFlightRefundOrder(FlightRefundOrder info) {
    int retCode = 0;


    em.persist(info);

    retCode = info.getId();
    if (retCode > 0) {
      OperationLog log = createFlightRefundOrderLog(info.getEnterpriseId(), info.getCustomer().getId(), info.getOperator(), retCode, "创建退票单");
      em.persist(log);
    }


    return retCode;
  }

  private OperationLog createFlightRefundOrderLog(int enterpriseId, final int customerId, String username, int refundOrderId, String remark) {
    OperationLog log = OperationLogFactory.createFlightRefundOrderOperationLog();
    log.setEnterpriseId(enterpriseId);
    log.setCustomerId(customerId);
    log.setOperator(username);
    log.setOrderId(refundOrderId);
    log.setContent(remark);

    return log;
  }

}
